package cn.org.eshow.service.impl;

import cn.org.eshow.bean.OrderBean;
import cn.org.eshow.bean.query.OrderItemQuery;
import cn.org.eshow.bean.query.ProductOrderQuery;
import cn.org.eshow.common.ShopDataVar;
import cn.org.eshow.common.page.Page;
import cn.org.eshow.component.getui.GetuiUtil;
import cn.org.eshow.component.pingpay.config.PingConfig;
import cn.org.eshow.component.qiniu.QiniuConfig;
import cn.org.eshow.component.qiniu.QiniuUtil;
import cn.org.eshow.dao.ProductOrderDao;
import cn.org.eshow.model.*;
import cn.org.eshow.service.*;
import cn.org.eshow.util.ExcelUtil;
import cn.org.eshow.util.OrderUtil;
import cn.org.eshow.util.StringUtil;
import com.pingplusplus.Pingpp;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Refund;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.jws.WebService;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

//import cn.org.eshow.service.MoneyManager;

@WebService(serviceName = "ProductOrderService", endpointInterface = "cn.org.eshow.service.ProductOrderManager")
@Service
public class ProductOrderManagerImpl extends GenericManagerImpl<ProductOrder, Integer> implements ProductOrderManager {

    @Autowired
    ProductOrderDao productOrderDao;
    @Autowired
    OrderStepManager orderStepManager;
    @Autowired
    BillManager billManager;
    @Autowired
    FinanceManager financeManager;
    @Autowired
    OrderItemManager orderItemManager;
    @Autowired
    ProductManager productManager;
    @Autowired
    UserCouponManager userCouponManager;
    @Autowired
    ProductItemManager productItemManager;
    @Autowired
    NotificationManager notificationManager;
    @Autowired
    MoneyManager moneyManager;

    public ProductOrderManagerImpl() {
    }

    @Autowired
    public ProductOrderManagerImpl(ProductOrderDao productOrderDao) {
        super(productOrderDao);
        this.productOrderDao = productOrderDao;
    }

    @Override
    public List<ProductOrder> list(ProductOrderQuery query) {
        return productOrderDao.list(query);
    }

    @Override
    public Page<ProductOrder> search(ProductOrderQuery query) {
        return productOrderDao.search(query);
    }

    @Override
    public ProductOrder check(ProductOrderQuery query) {
        List<ProductOrder> list = productOrderDao.list(query);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Integer count(ProductOrderQuery query) {
        List<ProductOrder> list = productOrderDao.list(query);
        return list.size();
    }

    @Override
    public synchronized void pay(Charge charge) {
        ProductOrderQuery productOrderQuery = new ProductOrderQuery();
        productOrderQuery.setNo(charge.getOrderNo().trim());
        productOrderQuery.setState(0);
        ProductOrder order = check(productOrderQuery);
        if (order != null) {

            order.setUpdateTime(new Date());
            order.setPay(charge.getAmount()/100.0);
            order.setPayState(1);//1已支付
            order.setState(1);//1配送状态
            order.setDeliveryState(0);//0待接单
            order.setCallback(charge.getId());
            order.setStatements("待接单");
            order = productOrderDao.save(order);

            String remark = "";//支付方式
            Money myMoney = moneyManager.mine(order.getUser());
            if (order.getPayment() == 0) {//0支付宝支付，1微信支付
                remark = "支付宝支付";
            } else if (order.getPayment() == 1) {
                remark = "微信支付";
            }else if(order.getPayment()==2){//余额支付
                remark = "余额支付";
                myMoney = moneyManager.frozen(myMoney, -order.getPrice());
            }
            //todo 需要补全money表信息 增加用户支出记录
            billManager.calc(order.getUser(), ShopDataVar.billCategory.用户.toString(), ShopDataVar.billType.消费支出.toString(), 0.0, order.getPay(),myMoney.getBalance(), "productOrder", order.getNo(), remark, 1, null);

            orderStepManager.save("付款成功", "付款成功", order);//新增订单步骤
            notificationManager.save(order.getUser(),Notification.Category.订单消息.toString(),"付款成功","请等待客服与您联系","","productOrder",order.getId().toString());
            GetuiUtil.pushMessage(order.getUser().getClientId(), "订单消息通知", "您的订单已支付完成，请等待客服人员联系", "productOrder", order.getId().toString());

            updateSales(order);//更新销售额

            //增加平台收入和记录
            Finance platFormFinance=financeManager.balance(order.getPrice());
            billManager.calc(null, ShopDataVar.billCategory.平台.toString(), ShopDataVar.billType.平台订单收入.toString(), order.getPrice(),0.0 , platFormFinance.getBalance(), "productOrder", order.getNo(), "", 1, null);


        }
    }


    @Override
    public ProductOrder save(ProductOrder productOrder, User user, List<Cart> carts, Address address) {
        if (productOrder.getUserCoupon() != null && productOrder.getUserCoupon().getId() != null) {//是否使用红包
            UserCoupon userCoupon = userCouponManager.get(productOrder.getUserCoupon().getId());
            userCouponManager.useCoupon(userCoupon);
        }

        Double price = 0.00; //订单总价格
        Double origPrice = 0.00; //订单原价
        for (Cart cart : carts) {
            ProductItem productItem = cart.getProductItem();
            origPrice += productItem.getPrice() * cart.getQuantity();
            price += productItem.getPrice() * cart.getQuantity();//计算订单总价格
        }
        productOrder.setPrice(price - productOrder.getDiscount() - productOrder.getCoupon());//计算商品实际价格(减去手工优惠价格-减去优惠金额)
        productOrder.setOrigPrice(origPrice);
        productOrder.setState(0);//待付款
        productOrder.setStatements("待付款");
        productOrder.setUser(user);
        productOrder.setCategory("用户订单");
        productOrder = updateAddress(productOrder, address);
        productOrder = productOrderDao.save(productOrder);

        for (Cart cart : carts) {
            ProductItem productItem = cart.getProductItem();
            OrderItem orderItem = new OrderItem();
            orderItem.setProductOrder(productOrder);
            orderItem.setProduct(productItem.getProduct());
            orderItem.setProductItem(productItem);
            orderItem.setNo(productOrder.getNo());
            orderItem.setType("");
            orderItem.setPrice(productItem.getPrice());
            orderItem.setOrigPrice(productItem.getPrice());
            orderItem.setQuantity(cart.getQuantity());
            orderItem.setUser(user);
            orderItem.setType("原价");
            orderItem = orderItemManager.save(orderItem);
        }
        orderStepManager.save("提交订单", "提交订单", productOrder);//新增订单步骤


        return productOrder;
    }

    @Override
    public ProductOrder save(ProductOrder productOrder, User user, String productItemIds, String quantities, Address address) {
        if (productOrder.getUserCoupon() != null && productOrder.getUserCoupon().getId() != null) {//是否使用红包
            UserCoupon userCoupon = userCouponManager.get(productOrder.getUserCoupon().getId());
            userCouponManager.useCoupon(userCoupon);
        }

        productOrder.setNo(OrderUtil.getOrderNo());
        Double price = 0.00; //订单总价格
        Double origPrice = 0.00; //订单原价
        String[] productItemIdArray = productItemIds.split(",");//药品ID数组
        String[] quantityArray = quantities.split(",");//药品数量数组
        for (int i = 0; i < productItemIdArray.length; i++) {
            ProductItem productItem = productItemManager.get(Integer.valueOf(productItemIdArray[i]));
            if (productItem != null) {
                origPrice += productItem.getPrice() * Integer.valueOf(quantityArray[i]);
                price += productItem.getPrice() * Integer.valueOf(quantityArray[i]);//计算订单总价格
            }
        }
        productOrder.setPrice(price - productOrder.getDiscount() - productOrder.getCoupon());//计算商品实际价格(减去手工优惠价格-减去优惠金额)
        productOrder.setOrigPrice(origPrice);
        productOrder.setState(0);//0付款状态
        productOrder.setPayState(0);//0待支付
        productOrder.setStatements("待付款");
        productOrder.setCategory("用户订单");
        productOrder.setUser(user);
        productOrder = updateAddress(productOrder, address);
        productOrder = productOrderDao.save(productOrder);
        for (int i = 0; i < productItemIdArray.length; i++) {
            ProductItem productItem = productItemManager.get(Integer.valueOf(productItemIdArray[i]));
            if (productItem != null) {
                OrderItem orderItem = new OrderItem();
                orderItem.setProductOrder(productOrder);
                orderItem.setProduct(productItem.getProduct());
                orderItem.setProductItem(productItem);
                orderItem.setNo(productOrder.getNo());
                orderItem.setType("");
                orderItem.setPrice(productItem.getPrice());
                orderItem.setOrigPrice(productItem.getPrice());
                orderItem.setQuantity(Integer.valueOf(quantityArray[i]));
                orderItem.setUser(user);
                orderItem.setType("原价");
                orderItem = orderItemManager.save(orderItem);
            }
        }

        orderStepManager.save("提交订单", "提交订单", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public ProductOrder cancel(ProductOrder productOrder) {
        productOrder.setUpdateTime(new Date());
        productOrder.setState(-1);
        productOrder.setStatements("已取消");
        productOrder = productOrderDao.save(productOrder);

        userCouponManager.turnBackUserCoupon(productOrder.getUserCoupon());//退还优惠券

        orderStepManager.save("订单已取消", "订单已取消", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public List<ProductOrder> list(String hql, Object[] params) {
        return productOrderDao.list(hql, params);
    }

    //    退款
    public synchronized void refund(Refund refund) {
        ProductOrderQuery productOrderQuery = new ProductOrderQuery();
        productOrderQuery.setCallback(refund.getCharge().trim());
        productOrderQuery.setRefundState(2);//2退款中（回调用）
        ProductOrder productOrder = check(productOrderQuery);
        if (productOrder != null) {
            productOrder.setUpdateTime(new Date());
            productOrder.setRefundState(1);//已退款
            productOrder.setStatements("已退款");
            productOrder.setState(3);//3 退款状态
            productOrder = productOrderDao.save(productOrder);

            //增加用户退款记录
            billManager.calc(productOrder.getUser(), ShopDataVar.billCategory.用户.toString(), ShopDataVar.billType.消费退款.toString(), 0.0, productOrder.getPay(), 0.0, "order", productOrder.getNo(), null, 1, null);

            userCouponManager.turnBackUserCoupon(productOrder.getUserCoupon());//退还优惠券

            notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"订单已退款","您的订单已退款到原来的账户中","","productOrder",productOrder.getId().toString());
            GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单已退款到原来的账户中", "productOrder", productOrder.getId().toString());

            orderStepManager.save("订单已取消", "订单已取消", productOrder);//新增订单步骤


            //添加平台线上退款和记录
            Finance platFormFinance=financeManager.balance(-productOrder.getRefundAmount());
            billManager.calc(null, ShopDataVar.billCategory.平台.toString(), ShopDataVar.billType.平台线上退款.toString(), 0.0,productOrder.getRefundAmount() , platFormFinance.getBalance(), "productOrder", productOrder.getNo(), "", 1, null);



        }
    }

    @Override
    public ProductOrder executeRefund(ProductOrder productOrder, Double refundPrice) {
        //退款流程
        Pingpp.apiKey = PingConfig.APIKEY;
        Pingpp.setVerifySSL(Boolean.FALSE);

        productOrder.setRefundAmount(StringUtil.toDecimal(refundPrice, 2));
        productOrder = productOrderDao.save(productOrder);
        if (StringUtils.isEmpty(productOrder.getCallback())) {
            return productOrder;
        }

        try {
            if (refundPrice > productOrder.getPay()) {
                refundPrice = productOrder.getPay();
            }

            try {
                //当前退款金额小于上一笔支付金额
                Charge ch = Charge.retrieve(productOrder.getCallback());
                Map<String, Object> refundMap = new HashMap<String, Object>();
                refundMap.put("amount", (int) (StringUtil.toDecimal(refundPrice, 2) * 100));
                refundMap.put("description", "订单退货退款");
                Map<String, String> initialMetadata = new HashMap<String, String>();
                initialMetadata.put("order_type", "productOrder");
                refundMap.put("metadata", initialMetadata);
                Refund re = ch.getRefunds().create(refundMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            productOrder.setUpdateTime(new Date());
            productOrder.setRefundState(2);//2退款中（回调用）
            productOrder.setState(3);//3 退款状态
            productOrder.setStatements("退款中");
            productOrder.setRefundAmount(StringUtil.toDecimal(refundPrice, 2));
            productOrder = productOrderDao.save(productOrder);

            GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", " 您的订单正在办理退款，资金到账时间1-2个工作日", "productOrder", productOrder.getId().toString());

            return productOrder;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ProductOrder delivery(ProductOrder productOrder) {
        productOrder.setUpdateTime(new Date());
        productOrder.setDeliveryState(1);//1待配送/待收货
        productOrder.setState(1);//1配送状态
        productOrder.setStatements("待配送");//商家已接单，等待用户确认收货
        productOrder = productOrderDao.save(productOrder);

        notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"商家已接单，等待用户确认收货","商家已接单，等待用户确认收货","","productOrder",productOrder.getId().toString());
        GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "商家已接单，等待用户确认收货", "productOrder", productOrder.getId().toString());

        orderStepManager.save("商家已接单，等待用户确认收货", "商家已接单，等待用户确认收货", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public ProductOrder conform(ProductOrder productOrder) {

        productOrder.setUpdateTime(new Date());
        productOrder.setDeliveryState(2);//2已收货
        productOrder.setState(2);//2完成状态（评价）
        productOrder.setCommentState(0);//0未评价
        productOrder.setStatements("待评价");//用户已验收,等待评价
        productOrder = productOrderDao.save(productOrder);

        notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"请尽快评价","您的订单尚未评价，请尽快评价","","productOrder",productOrder.getId().toString());
        GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单尚未评价，请尽快评价", "productOrder", productOrder.getId().toString());

        orderStepManager.save("完成", "完成", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public void updateSales(ProductOrder productOrder) {
        List<OrderItem> orderItems = orderItemManager.list(new OrderItemQuery(productOrder.getId()));
        for (OrderItem item : orderItems) {
            Product product = item.getProduct();
            if (product.getMonthSales() == null) {
                product.setMonthSales(0);
            }
            product.setMonthSales(product.getMonthSales() + item.getQuantity());
            product = productManager.save(product);
        }

    }

    @Override
    public ProductOrder updateAddress(ProductOrder productOrder, Address address) {
        if (address == null) {
            return productOrder;
        }
        productOrder.setDistrict(address.getDistrict());
        productOrder.setCity(address.getCity());
        productOrder.setProvince(address.getProvince());
        productOrder.setAddress(address.getAddr());
        productOrder.setAddrName(address.getName());
        productOrder.setAddrMobile(address.getMobile());
        return productOrder;
    }

    @Override
    public String exportExcel(List<ProductOrder> productOrders) {

        String classPath = this.getClass().getClassLoader().getResource("/").getPath();
        String path = "";

        if ("\\".equals(File.separator)) {
            String[] strPath = classPath.split("/");
            for (int i = 0; i < strPath.length; i++) {
                if (i > 0 && i < 5) {
                    path = path + strPath[i] + "/";
                }
            }
            path = path.replace("/", "\\");
        }

        //linux下
        if ("/".equals(File.separator)) {
            String[] strPath = classPath.split("/");
            for (int i = 0; i < strPath.length; i++) {
                if (i < 3) {
                    path = path + strPath[i] + "/";
                }
            }
            path = path.replace("\\", "/");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String random = sdf.format(new Date());
        for (int i = 0; i < 3; i++) {
            int r = (int) (Math.random() * 10);
            random = random + r;
        }

        File file1 = new File(path);
        //当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
        if (!file1.exists() && !file1.isDirectory()) {
            file1.mkdirs();
        }
        String key = "order" + random + ".xls";
        path = path + key;
        File file = new File(path);

        OutputStream output = null;
        List<OrderBean> orderBeanBeans = new ArrayList<OrderBean>();
        for (ProductOrder order : productOrders) {
            OrderBean orderBean = new OrderBean();
            orderBean.setNo(order.getNo());
            orderBean.setAddTime(order.getAddTime());
            orderBean.setPrice(order.getPrice());
            orderBean.setAddress(order.getAddress());
            orderBean.setAddrName(order.getAddrName());
            orderBean.setAddrMobile(order.getAddrMobile());
            orderBean.setStatements(order.getStatements());
            String orderMessage = "";
            List<OrderItem> orderItems = orderItemManager.list(new OrderItemQuery(order.getId()));
            for (OrderItem item : orderItems) {
                orderMessage += item.getProduct().getName() + " 数量：" + item.getQuantity()  + "，";
            }
            orderBean.setOrderItems(orderMessage);
            orderBeanBeans.add(orderBean);
        }
        ExcelUtil util = new ExcelUtil(OrderBean.class);
        try {
            output = new FileOutputStream(file);
            util.exportExcel(orderBeanBeans, "订单", orderBeanBeans.size(), output);

            String qiniuUrl = QiniuConfig.URL + "/" + key;
            String result = QiniuUtil.upload(QiniuConfig.BUCKET, path, key);
            if (StringUtils.isNotEmpty(result)) {

                file.delete();

                return qiniuUrl;
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}